Skip to main content link. Accesskey S
  • Help
  • HCL Logo
  • HCL Sametime wiki
  • THIS WIKI IS READ-ONLY. Individual names altered for privacy purposes.
  • HCL forums and blogs
  • Home
  • Product Documentation
  • Community Articles
  • Learning Center
Search
Community Articles > Sametime Proxy > Creating a customer service web application using Sametime - Part Two
  • Share Show Menu▼
  • Subscribe Show Menu▼

Recent articles by this author

Creating a customer service web application using Sametime - Part Three

Support Click-to-Chat with only a little coding: The Click-to-Chat pattern is becoming increasingly popular on customer-facing web sites. This series of three articles shows how to implement this using the Sametime Proxy features, with a simple automation servlet, or bot to manage ...

Creating a customer service web application using Sametime - Part Two

Support Click-to-Chat with only a little coding: The Click-to-Chat pattern is becoming increasingly popular on customer-facing web sites. This series of three articles shows how to implement this using the Sametime Proxy features, with a simple automation servlet, or bot to manage ...

Creating a customer service web application using Sametime - Part One

Support Click-to-Chat with only a little coding: The Click-to-Chat pattern is becoming increasingly popular on customer-facing web sites. This series of three articles shows how to implement this using the Sametime Proxy features, with a simple automation servlet, or bot to manage ...

Google Chrome extension for Click-to-Call

Make phone calls from any web page: This article describes an extension to the Google Chrome™ browser to allow highlighted phone numbers on an arbitrary web page to be called from Sametime Unified Telephony.

Internet Explorer extension for Click-to-Call

Make phone calls from any web page: This article describes an extension to Microsoft Internet Explorer™ to allow highlighted phone numbers on an arbitrary web page to be called from Sametime Unified Telephony.
Community articleCreating a customer service web application using Sametime - Part Two
Added by ~Vanessa Reachek | Edited by ~Kim Rehipigenflar on May 22, 2013 | Version 4
  • Actions Show Menu▼
expanded Abstract
collapsed Abstract
Support Click-to-Chat with only a little coding: The Click-to-Chat pattern is becoming increasingly popular on customer-facing web sites. This series of three articles shows how to implement this using the Sametime Proxy features, with a simple automation servlet, or bot to manage interactions.
Tags: Sametime Proxy, Customer Service Desk
ShowTable of Contents
HideTable of Contents
  • 1 Part 2: The Customer and Service Agent web interfaces
  • 2 A digression – Security
  • 3 The client side – the agent
  • 4 The client side – the customer experience
  • 5 The sample code
  • 6 Conclusion
  • 7 Resources
  • 8 About the authors
    • 8.1 Brendan Murray
    • 8.2 William Holmes

Part 2: The Customer and Service Agent web interfaces


The first part of this series showed how to use a server-side automaton or bot to manage connectivity across a customer service desk solution. This second part explains how the agent and customer web interfaces can be implemented using the Sametime Proxy SDK functions.


A digression – Security


A very important aspect of any web application nowadays is to minimize the risks associated with creating an online presence. This article deliberately does not include security functions in the code, in order to better illustrate the concepts here. However, it is something that a developer cannot ignore, which is why this section lists some of the aspects that must be addressed.

While the Sametime Proxy server sanitizes its inputs, any other input fields should be escaped by some mechanism like the Apache Commons Lang library. In particular this applies to the data supplied from the customer web page since this is the externally-facing code.

Listing 1: Sanitizing input

import org.apache.commons.lang3.StringEscapeUtils.escapeHtml3;

String newInput = escapeHtml3(inputData);


Another aspect of security is the concept of authentication. Since we allow anonymous users to connect, we have to allow anonymous users in the Sametime configuration. It is also important to understand that you can never be certain a user is who she says she is if she is not authenticated. To minimize the impact of this, we can restrict an anonymous user's ability to initiate chats in the Sametime Proxy's configuration file

Listing 2: Restricting anonymous users in stproxyconfig.xml
 <clientRestriction>
        <chat>
            <init>true</init>
        </chat>
    </clientRestriction>


Of course, a better mechanism to handle this situation is to ensure that users log in before accessing the chat function, if this is at all possible.

Note that the code samples accompanying this article refer to JavaScript innerHTML for the sake of simplicity. However, there is a possibility that this can facilitate cross-side scripting (XSS) attacks, so it is safer to construct the DOM fragment correctly instead.

The client side – the agent


This side of the system is the Customer Service Desk application. In our sample, it merely shows the Sametime interactions whereas in a production environment it would have all the other usual customer service functions.

The UI is quite simple. Initially the window displays the usual username and password for the agent to login which, in this case, is achieved by means of the loginByPassword() api.

Figure 1: The initial Agent screen.

When the agent has successfully logged in, we create a livename model for the bot. This allows us to check if the bot is actually active. If it is, a chat channel is opened with the bot and we set up a couple of listeners on this chat, one to catch any incoming message, and one to react if the bot logs out:

Listing 3: Initializing the agent-bot communication

botLNModel = stproxy.getLiveNameModel("servicebot", {"forceWatchlist":true});

// Get (or create) a chat model for the support bot
var chatArgs = {
	"isAnonymous" : false,
	"isRichText" : false,
	"isEmbeded" :  true
};

// If the bot is logged in and ready
if (botLNModel.status ==  stproxy.awareness.AVAILABLE) {
	// Establish a chat channel
	botChatModel = stproxy.getChatModel(botLNModel.id, chatArgs);

	// If the bot sends a message
	evtBotMessage = dojo.connect(botChatModel,"onMessage", 
				dojo.hitch(this, processUserData));

	// If the bot logs out
	evtBotCLosed  = dojo.connect(botChatModel,"onChatClosed", 
				dojo.hitch(this,function() { agentLogout(true); }));	
} 


At this point, we're waiting for the bot to let us know that a customer is waiting for attention, so the UI displays an empty form.


Figure 2: The agent screen awaiting input from the Bot.


Now, when a customer requests support of the bot, it sends a chat message with the customer's details to the agent. This information is sent in JSON format, so we have to parse the parts of the message before using them. Fortunately, we can use the browser functions to achieve this, and the fields are then used to populate the screen fields as well as to create a livename – note that the livename's display name is explicitly set here:

Listing 4: Establishing the connection to the customer

function processUserData(json) {
   // Parse the JSON data
   var inpData = window.JSON.parse(json);

   // Set the screen fields to the various values
   dojo.byId("emailnode").innerHTML = inpData.email;
   dojo.byId("phonenode").innerHTML = inpData.phone;
   dojo.byId("reasonnode").innerHTML = inpData.reason;

   // Create a livename for the customer
   custLiveName = new sametime.LiveName({ "userId":inpData.id,
                                          "isAnonymous":true,
                                          "displayName":inpData.name },
                                          dojo.byId("lnnode"));

   
   // Create a chat channel with the customer
   custChatModel = stproxy.getChatModel(inpData.id, { "isAnonymous" : false,
                                          "isEmbedded" : false,
                                          "isRichText" : true });

   // Attach a listener for the event marking the end of the chat
   evtCustClosed = dojo.connect(custChatModel, "onChatClosed",
                                      dojo.hitch(this, cleanupCustChat));

   // Change the agent's status to in a meeting
   stproxy.status.set(stproxy.awareness.IN_MEETING, "Chatting with a customer",
                      statusSet, generalError);
} 


At this point, the screen fields are populated, and the agent can chat with the customer via the livename.


Figure 3: The populated agend display with an active LiveName

While this displays the usual Sametime functions, typically you would override the various menu items in order to optimise the customer experience.

The client side – the customer experience



In order to exclude any overhead of loading the Sametime markup when its not needed, the chat function is hosted in a separate popup page. The customer clicks on the “Click here” message, and the popup shows, allowing the customer to specify the relevant details.




Figure 4: The customer page.

The configuration on the page illustrates how certain Sametime functions can be disabled. This is done by disabling some plugins:

Listing 5: Disabling Sametime functions

plugins: {
   "cmpFile": false,
   "cmpTools": false,
   "cmpHelp": false,
   "lnmpBizCard":false
}

Here, the chat menu plugins for the File, Tools and Help menus are disabled, along with the livename menu plugin for the business card: these have the prefix of cmp and lnmp respectively.

Once the customer has input the information and clicks “OK”, it logs the customer in as an anonymous user. In order to initiate the session with the agent, the customer tells the bot via a call to its REST API:

Listing 6: Talking to the bot

dojo.xhrPost({ // 
  url: "http://coalfish.mul.ie.ibm.com:8080/CustomerServiceDesk/ServiceServlet", 
  content: {
      id: response.id,
      user: dojo.byId("nametxt").value,
      phone: dojo.byId("phntxt").value,
      email: dojo.byId("emailtxt").value,
      reason: dojo.byId("reason").value
  },

   timeout: 5000, // Time in milliseconds

   load: function(response, ioArgs) {
             dojo.style(dojo.byId("userForm"), {display:'none'});
             dojo.style(dojo.byId("chatWindow"), {display:'block'});
             dojo.byId("message").innerHTML = response;
             return response; 
         },

   error: function(response, ioArgs) {
             console.error("HTTP status code: ", ioArgs.xhr.status);
             dojo.byId("message").innerHTML = 'Could not connect to Sametime';
             return response;
         }
});



The code listens for any chat messages to arrive and then processes the chat:

Listing 7: Capturing chat messages

evtHandle = dojo.connect(stproxy.chat, "onChatData",
                                       dojo.hitch(this, createChatWindow));


The code executed when the chat message arrives first creates a chat model for this chat. This grants the code more control of the chat interactions, and facilitates the creation of an embedded chat.

Listing 8: Starting the chat

function createChatWindow(isRichtext, userId) {
   var chatArgs = {
      "isAnonymous" : false,
      "isRichText" :  isRichtext,
      "isEmbeded" :   true
   };

   // Get the chat model to allow us create a chat
   theModel = stproxy.getChatModel(userId, chatArgs);

   // Create an embedded chat
   theChat = new sametime.Chat({ model: theModel },
                           document.createElement("div"));
   dojo.byId("myChat").appendChild(theChat.domNode);
   dojo.empty("message");

   // We don't want to redo this, so remove the event
   dojo.disconnect(evtHandle);

   // Terminate the connection when the agent closes
   evtHandle = dojo.connect(theModel, "onChatClosed",
                                      dojo.hitch(this,closeMe));
}


The chat window then displays embedded in the window, and the two partners chat as usual.

When the agent closes the chat window, we capture this event and call the closeMe() function, which terminates the connection to Sametime.

Listing 9: Terminating the Sametime session

function closeMe() {
   if (stproxy.isLoggedIn) {
      if (theChat)
         theChat.destroy();
      if (theModel)
         theModel.close();
      stproxy.login.logout();
      alert("Have a nice day!");
   }
   self.close();
}	


You'll notice that it terminates with self.close() - in this case, self refers to the chatModel to which this function is connected. Closing the chatModel in this way ensures that the connection can't be reopened or otherwise misused.

The sample code


The attached code should be dropped into the code from the first article of this series since they together provide the sample application. In the code, specifically in agent.jsp and popup.jsp, there are references to servers that need to be updated. To make it easier, these are marked with the string which should be replaced by the URL of your Sametime Proxy server including the port, if required.

The attached code uses the Dojo Toolkit, but in fact, this is not required. If you wish to make the solution framework-agnostic, follow the guidlines in the link in the references below.

Conclusion


This second part of the series shows how the customer initiates the request for a chat, but the chat itself is initiated by the agent side. The next and final part of the series will show show to add some more advanced functions to the application, such as inviting a supervisor into the chat, i.e. promoting the chat to n-way.

Creating a customer service web application using Sametime - Part One
Creating a customer service web application using Sametime - Part Three

Resources


Sametime Standard V8.5.2 SDK IFR 1 Multiplatform: https://ibm.biz/BdxaNm
developerWorks® IBM Sametime product page: https://ibm.biz/BdxVZU
Integrating IBM Sametime in a Web application without the Dojo Toolkit: https://ibm.biz/BdxSSJ

About the authors



Brendan Murra

y
Brendan joined Lotus Development in 1991 and was acquired, along with the rest of the company, by IBM in 1995. Most recently he has been working on Sametime with a particular emphasis on its Web functionality. You can reach him at brendan_murray@ie.ibm.com

William Holmes


William has been with IBM since 2007 and is currently the Technical Lead for the Sametime Proxy Web client. You can reach him at HOLMESW@ie.ibm.com

  • Actions Show Menu▼


expanded Attachments (1)
collapsed Attachments (1)
Edit the article to add or modify attachments.
File TypeSizeFile NameCreated OnDelete file
application/x-zip 107 KB CustomerServiceDesk-part2.zip 5/9/13, 4:07 PM
expanded Versions (4)
collapsed Versions (4)
Version Comparison     
VersionDateChanged by              Summary of changes
This version (4)May 22, 2013, 7:08:06 PM~Kim Rehipigenflar  
3May 22, 2013, 4:38:58 PM~Sarah Brewevitchynds  
1May 13, 2013, 8:38:17 PM~Sarah Brewevitchynds  
1May 13, 2013, 8:54:47 PM~Sarah Brewevitchynds  
expanded Comments (0)
collapsed Comments (0)
Copy and paste this wiki markup to link to this article from another article in this wiki.
Go ElsewhereStay ConnectedAbout
  • HCL Software
  • HCL Digital Solutions community
  • HCL Software Support
  • BlogsDigital Solutions blog
  • Community LinkHCL Software forums and blogs
  • About HCL Software
  • Privacy
  • Accessibility